```
\newcommand{\commonfolder}{../../common-files}
\newcommand{\webcommon}{../Web_Common}

\input{\commonfolder/header}
\input{\commonfolder/copyright}


\newcommand{\bash}{{\tt bash}\xspace}
\newcommand{\Bash}{{\tt Bash}\xspace}

\lhead{\bfseries SEED Labs -- Shellshock 攻击实验}

\begin{document}

\begin{center}
{\LARGE Shellshock 攻击实验}
\end{center}

\seedlabcopyright{2006 - 2016}

\section{概述}

在2014年9月24日，一个严重的 bash 漏洞被发现。这次漏洞被称为 Shellshock，它可以利用许多系统，并且可以从远程或本地机器发起攻击。在这次实验中，学生需要对这个攻击进行研究，以便理解 Shellshock 的漏洞。该实验的学习目标是让学生亲身体验这个有趣的攻击、了解其工作原理，并思考我们能从这种攻击中学到哪些教训。第一次发布此实验是在2014年9月29日，距离发现攻击仅五天后。它被分配给2014年9月30日在我们的计算机安全课程中。SEED 项目的重要使命之一是快速将真实攻击转化为教育材料，以便教师能够及时将其引入课堂，并让学生成为现实世界中发生的事情保持关注。该实验包括以下主题：

\begin{itemize}[noitemsep]
\item Shellshock
\item 环境变量 
\item bash 中的函数定义
\item Apache 和 CGI 程序
\end{itemize}

\paragraph{参考资料和视频。}
有关 Shellshock 攻击的详细内容，参见以下部分：

\begin{itemize}
\item SEED 书籍中的第3章，《\seedbook》
\item Udemy 上的 SEED 讲座中的第3节，《\seedcsvideo》
\end{itemize}

\paragraph{实验环境。} \seedenvironmentB \nodependency

% *******************************************
% SECTION
% *******************************************
\section{环境设置} 

% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{DNS 设置}

在我们的配置中，Web 服务器容器的 IP 地址是 \texttt{10.9.0.5}。服务器的主机名为 \texttt{www.seed-server.com}。我们需要将这个名称映射到 IP 地址上，请在 \texttt{/etc/hosts} 中添加以下内容。你需要使用 root 权限来修改此文件：

\begin{lstlisting}
10.9.0.5       www.seed-server.com
\end{lstlisting}

% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{容器设置和命令}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input{\commonfolder/container/setup}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% -------------------------------------------
% SUBSECTION
% -------------------------------------------
\subsection{Web 服务器和 CGI} 

在此次实验中，我们将对 Web 服务器容器发起 Shellshock 攻击。许多 Web 服务器启用了 CGI（通用网关接口），这是一种用于生成网页动态内容以及 Web 应用程序的标准方法。许多 CGI 程序是 shell 脚本，因此实际的 CGI 程序运行之前会先调用一个 shell 程序，并且这种调用是由远程计算机上的用户触发的。如果该 shell 程序是一个易受攻击的 bash 程序，我们可以通过利用 Shellshock 漏洞来获得服务器上的权限。

在我们的 Web 服务器容器中，已经设置了一个非常简单的 CGI 程序（称为 \texttt{vul.cgi}）。它只是一个使用 shell 脚本输出“Hello World”的程序。CGI 程序被放置在 Apache 的默认 CGI 文件夹 \texttt{/usr/lib/cgi-bin} 中，并且必须是可执行的。

\begin{lstlisting}[caption=\texttt{vul.cgi}] 
(*@\textbf{\#!/bin/bash\_shellshock}@*)          

echo "Content-type: text/plain"
echo
echo
echo "Hello World"
\end{lstlisting}

CGI 程序使用 \texttt{/bin/bash\_shellshock}（第一行）而不是 \texttt{/bin/bash}。这行指定了用于运行脚本的 shell 程序。我们需要在此次实验中使用易受攻击的 bash。

要从 Web 访问 CGI 程序，我们可以通过输入以下 URL 使用浏览器或使用 \url{http://www.seed-server.com/cgi-bin/vul.cgi} 的命令行程序 \texttt{curl} 完成相同操作。请确保 Web 服务器容器正在运行。

\begin{lstlisting}
$ curl http://www.seed-server.com/cgi-bin/vul.cgi
\end{lstlisting}

% *******************************************
% SECTION
% ******************************************* 
\section{实验任务}

有关 Shellshock 攻击的详细指南可以在 SEED 书籍中找到，因此我们不会在实验描述中重复这些指南。

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务1：试验 Bash 函数}

Ubuntu 20.04 的 bash 程序已经打上了补丁，因此不再易受 Shellshock 攻击。为了这次实验的目的，在容器（位于 \texttt{/bin} 内）中安装了一个易受攻击的 bash 版本。该程序也可以在 \texttt{Labsetup} 文件夹内的 \texttt{image\_www} 中找到，它的名称是 \texttt{bash\_shellshock}。我们需要在此任务中使用此 bash 程序。您可以在容器内或直接在您的计算机上运行此 shell 程序。容器手册链接在实验网站上。

请设计一个实验来验证这个 bash 是否易受 Shellshock 攻击。在补丁后的版本 \texttt{/bin/bash} 上进行同样的实验并报告观察结果。

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务2：通过环境变量向 Bash 传递数据}

为了利用基于 bash 的 CGI 程序中的 Shellshock 漏洞，攻击者需要将他们的数据传递给易受攻击的 bash 程序，并且这些数据需要通过环境变量来传递。在本任务中，我们需要看到如何实现这一目标。我们已经在服务器上提供了另一个 CGI 程序（\texttt{getenv.cgi}），帮助您识别用户数据可以进入 CGI 程序中的哪些环境变量。此 CGI 程序会打印所有其环境变量。

\begin{lstlisting}[caption=\texttt{getenv.cgi}]
#!/bin/bash_shellshock             

echo "Content-type: text/plain"
echo
echo "****** Environment Variables ******"
strings /proc/$$/environ            (*@\ding{192}@*)
\end{lstlisting}

\paragraph{任务2.A：使用浏览器。}
在上面的代码中，第 \ding{192} 行打印了当前进程的所有环境变量的内容。通常，如果您通过浏览器访问 CGI 程序，您会看到类似以下内容。请确定哪些环境变量值是浏览器设置的。您可以打开浏览器中的 HTTP 头实时扩展以捕获 HTTP 请求，并将请求与服务器输出的环境变量进行比较。请在实验报告中包含您的调查结果。

\begin{lstlisting}
****** Environment Variables ******
HTTP_HOST=www.seed-server.com
HTTP_USER_AGENT=Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:83.0) ...
HTTP_ACCEPT=text/html,application/xhtml+xml,application/xml;q=0.9, ...
HTTP_ACCEPT_LANGUAGE=en-US,en;q=0.5
HTTP_ACCEPT_ENCODING=gzip, deflate
...
\end{lstlisting}

 
\paragraph{任务2.A：使用 \texttt{curl}} 如果我们想将环境变量数据设置为任意值，我们需要修改浏览器的行为，这将会太复杂。幸运的是，有一个名为 \texttt{curl} 的命令行工具，它允许用户控制 HTTP 请求中的大多数字段。以下是其中一些有用的选项：（1）\texttt{-v} 字段可以打印出 HTTP 请求的头部；（2）\texttt{-A}, \texttt{-e}, 和 \texttt{-H} 选项可以设置请求头部中的某些字段，并且您需要确定每个选项设置了哪些字段。请在实验报告中包含您的发现。以下是使用这些字段的一些示例：

\begin{lstlisting}
$ curl -v www.seed-server.com/cgi-bin/getenv.cgi
$ curl -A "my data" -v www.seed-server.com/cgi-bin/getenv.cgi
$ curl -e "my data" -v www.seed-server.com/cgi-bin/getenv.cgi
$ curl -H "AAAAAA: BBBBBB" -v www.seed-server.com/cgi-bin/getenv.cgi
\end{lstlisting}
 
根据此实验，请描述哪些 \texttt{curl} 的选项可以用于将数据注入目标 CGI 程序的环境变量。

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务3：发起 Shellshock 攻击}

我们现在可以发起 Shellshock 攻击。这次攻击并不依赖于 CGI 程序的内容，因为它针对的是在实际执行 CGI 脚本之前被调用的 bash 程序。您的工作是通过以下 URL 发起攻击 \url{http://www.seed-server.com/cgi-bin/vul.cgi} ，从而使服务器运行任意命令。

如果您的命令有纯文本输出，并且您希望返回该输出，输出需要遵循一个协议：它应该以 \texttt{Content\_type: text/plain} 开始，后面是一个空行，然后可以放置您的纯文本输出。例如，如果您希望服务器返回其文件夹中的文件列表，那么您的命令将如下所示：

\begin{lstlisting}
echo Content-type: text/plain; echo; /bin/ls -l
\end{lstlisting}

在此任务中，请使用三种不同的方法（即三个不同 HTTP 头字段）发起针对目标 CGI 程序的 Shellshock 攻击。您需要实现以下目标：对于每个目标，您只需要使用一种方法，但总共需要使用三种不同方法。

\begin{itemize}
\item 任务3.A: 让服务器返回 \texttt{/etc/passwd} 文件的内容。
\item 任务3.B: 让服务器告诉您其进程的用户 ID。您可以使用 \texttt{/bin/id} 命令来打印该信息。
\item 任务3.C: 让服务器在 \texttt{/tmp} 文件夹中创建一个文件。您需要进入容器查看是否创建了该文件，或者使用另一个 Shellshock 攻击列出 \texttt{/tmp} 文件夹的内容。
\item 任务3.D: 删除您刚刚在 \texttt{/tmp} 文件夹中创建的文件。
\end{itemize}

\paragraph{问题。}请回答以下问题：
\begin{itemize}
\item 问题1：您是否可以从服务器窃取 \texttt{/etc/shadow} 文件的内容？为什么或为什么不？
    实验3.B 中获得的信息应该为您提供线索。

\item 问题2：HTTP GET 请求通常将数据附加到 URL 后的 \texttt{?} 符号之后。这可能是我们可以使用来发起攻击的另一种方法。以下面的例子为例，我们将在 URL 中附加一些数据，并发现这些数据被用作设置以下环境变量：

    \begin{lstlisting}
    $ curl "http://www.seed-server.com/cgi-bin/getenv.cgi?AAAAA"
    ...
    QUERY_STRING=AAAAA
    ...
    \end{lstlisting}

    我们可以使用这种方法来发起 Shellshock 攻击吗？请进行实验并根据实验结果得出结论。
     
\end{itemize}

  


% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务4：通过 Shellshock 攻击获取逆向 shell}

Shellshock 漏洞允许攻击者在目标机器上运行任意命令。在实际攻击中，而不是硬编码命令到攻击中，攻击者通常选择运行一个 shell 命令，这样他们可以使用此 shell 来执行其他命令，只要 shell 程序存活即可。
为了实现这一目标，攻击者需要运行一个逆向 shell。

逆向 shell 是由一台机器上的 shell 进程启动的，在远程计算机上控制其输入和输出。基本上，shell 在受害者的机器上运行，但它从攻击者机器接收输入并也在攻击者机器上打印输出。逆向 shell 为攻击者提供了一种方便的方式来在受感染机器上执行命令。有关如何创建逆向 shell 的详细说明可以在 SEED 书籍中找到。我们还将其总结在 Section~\ref{shellshock:sec:reverseshell} 中。
在此任务中，您需要演示如何使用 Shellshock 攻击从受害方获得一个逆向 shell。

% -------------------------------------------
% SUBSECTION
% ------------------------------------------- 
\subsection{任务5：使用已打补丁的 Bash}

现在，我们来使用已经打过补丁的 bash 程序。程序 \texttt{/bin/bash} 是一个经过修补版本。
请将 CGI 程序的第一行替换为这个程序。重新执行任务3并描述观察结果。

% *******************************************
% SECTION
% ******************************************* 
\section{创建逆向 shell 的指南}
\label{shellshock:sec:reverseshell}

\input{\commonfolder/guidelines/reverse_shell}





% *******************************************
% SECTION
% ******************************************* 
\section{提交说明}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\input{\commonfolder/submission}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\end{document}
```